package com.hzy.oms.controller;

import com.alibaba.fastjson2.JSONObject;
import com.hzy.config.LocalDataUtil;
import com.hzy.constant.Constants;
import com.hzy.oms.domain.bo.OrderCreateBo;
import com.hzy.oms.domain.bo.OrderInfoBo;
import com.hzy.oms.domain.vo.CountOrderVo;
import com.hzy.oms.domain.vo.OrderCalcVO;
import com.hzy.oms.domain.vo.OrderInfoVo;
import com.hzy.oms.request.DataIdsRequest;
import com.hzy.oms.request.OrderPayRequest;
import com.hzy.oms.response.OrderPayResponse;
import com.hzy.oms.service.IOrderInfoService;
import com.hzy.oms.service.OrderPayService;
import com.hzy.ums.domain.bo.form.OrderSubmitForm;
import com.hzy.ums.domain.vo.MemberVo;
import com.hzy.utils.RedisExUtils;
import com.ruoyi.common.annotation.RepeatSubmit;
import com.ruoyi.common.core.domain.PageQuery;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.utils.redis.RedisUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.web.bind.annotation.*;

import java.time.Duration;

@Slf4j
@RestController
@RequiredArgsConstructor
@RequestMapping("/oms/order")
public class OrderController {

    private final IOrderInfoService orderInfoService;

    private final OrderPayService orderPayService;

    @RepeatSubmit
    @PostMapping("/add")
    public R<Long> submit(@RequestBody OrderSubmitForm form) {
        MemberVo member = (MemberVo) LocalDataUtil.getVar(Constants.MEMBER_INFO);
        Long memberId = member.getId();
        String redisKey = "oms_order_add" + memberId;
        String redisValue = memberId + "_" + System.currentTimeMillis();
        try{
            String existJobInfo = RedisUtils.getCacheObject(redisKey);
            if (StringUtils.isNotEmpty(existJobInfo)) {
                throw new Exception(String.format("获取锁失败: redisKey: %s, existJobInfo: %s", redisKey, existJobInfo));
            }
            RedisUtils.setCacheObject(redisKey, redisValue, Duration.ofSeconds(60));
            return R.ok(orderInfoService.submit(form, member));
        }catch (Exception e){
            log.info("创建订单方法异常", e);
            throw new RuntimeException("服务繁忙，稍后再试");
        }finally {
            try {
                RedisUtils.deleteObject(redisKey);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
//    @PostMapping("orders")
//    public R<Page<OrderVO>> queryOrderPage(@RequestBody OrderQuery query, Pageable pageReq) {
//        return R.ok(orderInfoService.queryOrderPage(query, pageReq));
//    }

    /**
     * 下单前校验
     * @param bo
     * @return
     */
    @PostMapping("/addOrderCheck")
    public R<OrderCalcVO> addOrderCheck(@RequestBody OrderCreateBo bo){
        return R.ok(orderInfoService.addOrderCheck(bo));
    }


    /**
     * 查询订单列表
     */
    @GetMapping("/page")
    public TableDataInfo<OrderInfoVo> orderPage(OrderInfoBo bo, PageQuery pageQuery) {
        MemberVo member = (MemberVo) LocalDataUtil.getVar(Constants.MEMBER_INFO);
        bo.setMemberId(member.getId());
        return orderInfoService.orderPage(bo, pageQuery);
    }

    /**
     * 订单详情
     * @param orderId
     * @return
     */
    @GetMapping("/orderDetail")
    public R<OrderInfoVo> orderDetail(@RequestParam(required = false) Long orderId){
        if (orderId == null){
            throw new RuntimeException("系统繁忙");
        }
        return R.ok(orderInfoService.orderDetail(orderId));
    }

    /**
     * 确认收货
     * @param orderId
     * @return
     */
    @GetMapping("/orderComplete")
    public R<String> orderComplete(Long orderId) {
        log.info("确认收货，订单id："+orderId);
        String redisKey = "h5_oms_order_complete_"+orderId;
        String redisValue = orderId+"_"+System.currentTimeMillis();
        try{
            RedisUtils.setCacheObject(redisKey, redisValue, Duration.ofSeconds(60));
            return R.ok(orderInfoService.orderComplete(orderId));
        }catch (Exception e){
            log.error("确认收货异常",e);
            throw new RuntimeException(e.getMessage());
        }finally {
            try{
                RedisUtils.deleteObject(redisKey);
            }catch (Exception e){
                log.error("",e);
            }
        }
    }

    /**
     * 订单数量统计
     * @return
     */
    @GetMapping("/countOrder")
    public R<CountOrderVo> orderNumCount(){
        MemberVo member = (MemberVo) LocalDataUtil.getVar(Constants.MEMBER_INFO);
        Long memberId = member.getId();
        return R.ok(orderInfoService.orderNumCount(memberId));
    }

    /**
     * 取消订单
     * @param request
     * @return
     */
    @PostMapping("/orderCancel")
    public R<String> orderCancel(@RequestBody DataIdsRequest request){
        MemberVo member = (MemberVo) LocalDataUtil.getVar(Constants.MEMBER_INFO);
        String redisKey = "h5_oms_order_cancel_"+ request.getIdList().get(0);
        String redisValue = request.getIdList().get(0)+"_"+System.currentTimeMillis();
        try{
            RedisUtils.setCacheObject(redisKey, redisValue, Duration.ofSeconds(60));
            return R.ok(orderInfoService.orderBatchCancel(request.getIdList(), member.getId()));
        }catch (Exception e){
            log.error("订单取消方法异常",e);
            throw new RuntimeException("订单取消失败");
        }finally {
            try{
                RedisUtils.deleteObject(redisKey);
            }catch (Exception e){
                log.error("",e);
            }
        }
    }

    /***
     * 订单支付
     * @param req
     * @return
     */
    @RepeatSubmit
    @PostMapping("/orderPay")
    public R<OrderPayResponse> orderPay(@RequestBody OrderPayRequest req) {
        log.info("订单支付", "提交的数据：" + JSONObject.toJSONString(req));
        String redisKey = "h5_oms_order_pay_" + req.getPayId();
        String redisValue = req.getPayId() + "_" + System.currentTimeMillis();
        try {
            RedisExUtils.lock(redisKey, redisValue, 60);
            MemberVo member = (MemberVo) LocalDataUtil.getVar(Constants.MEMBER_INFO);
            Long memberId = member.getId();
            req.setMemberId(memberId);
            return R.ok(orderPayService.orderPay(req));
        } catch (Exception e) {
            log.error("支付方法异常", e);
            throw new RuntimeException(e.getMessage());
        } finally {
            try {
                RedisExUtils.unLock(redisKey, redisValue);
            } catch (Exception e) {
                log.error("", e);
            }
        }
    }

}
